package com.version1.diabeco.data.glucosa;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;

import com.version1.diabeco.data.AbstractDao;
import com.version1.diabeco.data.DiabecoContract;
import com.version1.diabeco.model.glucosa.Glucosa;
import com.version1.diabeco.model.medicacion.Medicacion;


public final class GlucosaDaoImpl extends AbstractDao implements GlucosaDao {

	
	
	private Context context;

	private static GlucosaDaoImpl instance;

	private GlucosaDaoImpl(Context context) {
		super(context);
	}

	/**
	 * Retrieves the singleton instance. Receives a context which is used for database initialization but also stored
	 * for subsequent sql operation calls.
	 * 
	 * This method is thread-safe.
	 * 
	 * @return GlucosaDao with the instance.
	 */
	public static synchronized GlucosaDaoImpl getInstance(Context context) {
		if (instance == null) {
			instance = new GlucosaDaoImpl(context);
		}

		instance.setContext(context);

		return instance;
	}

	public Context getContext() {
		return context;
	}

	public void setContext(Context context) {
		this.context = context;
	}

	@Override
	public Long count() {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public Glucosa selectById(Long id) {

		Glucosa result = null;

		SQLiteDatabase db = GlucosaDaoImpl.getInstance(this.getContext()).getReadableDatabase();

		// Define a projection that specifies which columns from the database
		// you will actually use after this query.
		String[] projection = { DiabecoContract.RegistroGlucosa._ID,
				DiabecoContract.RegistroGlucosa.COLUMNA_ALIAS,
				DiabecoContract.RegistroGlucosa.COLUMNA_FECHA,
				DiabecoContract.RegistroGlucosa.COLUMNA_CANTIDAD,
				DiabecoContract.RegistroGlucosa.COLUMNA_UM_GLUCOSA,
				DiabecoContract.RegistroGlucosa.COLUMNA_NIVEL_RIESGO,
				DiabecoContract.RegistroGlucosa.COLUMNA_MOMENTO,
				DiabecoContract.RegistroGlucosa.COLUMNA_CUANDO,
				DiabecoContract.RegistroGlucosa.COLUMNA_MUJER,
				DiabecoContract.RegistroGlucosa.COLUMNA_OBSERVACIONES,
				DiabecoContract.RegistroGlucosa.COLUMNA_NOTA };

		String selection = DiabecoContract.RegistroGlucosa._ID + " = ?";
		String[] selectionArgs = { id.toString() };

		// How you want the results sorted in the resulting Cursor
		String sortOrder = DiabecoContract.RegistroGlucosa.COLUMNA_FECHA + " DESC";

		Cursor cursor = db.query(DiabecoContract.RegistroGlucosa.TABLE_NAME, // The table to query
				projection, // The columns to return
				selection, // The columns for the WHERE clause
				selectionArgs, // The values for the WHERE clause
				null, // don't group the rows
				null, // don't filter by row groups
				sortOrder // The sort order
				);

		cursor.moveToFirst();
		result = this.retrieveGlycemiaMeasureFromCursor(cursor);
		
		db.close();
		return result;
	}

	@Override
	public List<Glucosa> selectBetweenDates(Date from, Date to) {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public List<Glucosa> selectAll() {
		List<Glucosa> result = new ArrayList<Glucosa>();

//		GlucosaDaoImpl.getInstance(this.getContext()).getReadableDatabase();
		
		SQLiteDatabase db = GlucosaDaoImpl.getInstance(this.getContext()).getReadableDatabase();

		// Define a projection that specifies which columns from the database
		// you will actually use after this query.
		String[] projection = { DiabecoContract.RegistroGlucosa._ID,
				DiabecoContract.RegistroGlucosa.COLUMNA_ALIAS,
				DiabecoContract.RegistroGlucosa.COLUMNA_FECHA,
				DiabecoContract.RegistroGlucosa.COLUMNA_CANTIDAD,
				DiabecoContract.RegistroGlucosa.COLUMNA_UM_GLUCOSA,
				DiabecoContract.RegistroGlucosa.COLUMNA_NIVEL_RIESGO,
				DiabecoContract.RegistroGlucosa.COLUMNA_ICON_RESOURCE_ID,
				DiabecoContract.RegistroGlucosa.COLUMNA_MOMENTO,
				DiabecoContract.RegistroGlucosa.COLUMNA_CUANDO,
				DiabecoContract.RegistroGlucosa.COLUMNA_MUJER,
				DiabecoContract.RegistroGlucosa.COLUMNA_OBSERVACIONES,
				DiabecoContract.RegistroGlucosa.COLUMNA_NOTA };

		String selection = null;
		String[] selectionArgs = null;

		// How you want the results sorted in the resulting Cursor
		String sortOrder = DiabecoContract.RegistroGlucosa.COLUMNA_FECHA + " DESC";

		Cursor cursor = db.query(DiabecoContract.RegistroGlucosa.TABLE_NAME, // The table to query
				projection, // The columns to return
				selection, // The columns for the WHERE clause
				selectionArgs, // The values for the WHERE clause
				null, // don't group the rows
				null, // don't filter by row groups
				sortOrder // The sort order
				);

		while (cursor.moveToNext()) {
			Glucosa glucosa = this.retrieveGlycemiaMeasureFromCursor(cursor);
			result.add(glucosa);
		}
		
		db.close();
		return result;
	}
	
	@Override
	public List<Glucosa> select5Dias() {

		// FIXME deberia filtrar directo en la base.
		List<Glucosa> lista5dias = new ArrayList<Glucosa>();
		List<Glucosa> listaCompleta = this.selectAll();
		 
		Calendar c = Calendar.getInstance();
		Date now = new Date();
		c.setTime(now);
		c.add(Calendar.DATE, -5);
		c.clear(Calendar.HOUR_OF_DAY);
		c.clear(Calendar.MINUTE);
		Long hace5diasDate = c.getTime().getTime();

		for (Glucosa glucosa : listaCompleta) {
			if (glucosa.getFecha() > hace5diasDate) {
				lista5dias.add(glucosa);
			}
		}
		
		return lista5dias;
	}
	
	//Agregar parametro observaciones
	public List<Glucosa> selectBetweenDatesAndValues(Calendar fromDate, Calendar toDate, Float umbralBajo, Float umbralAlto, long rango, long observaciones) {
		List<Glucosa> result = new ArrayList<Glucosa>();
	
		//Agregar SYSTEM.OUT para asegurar que llega parametro
		
		GlucosaDaoImpl.getInstance(this.getContext()).getReadableDatabase();
		
		SQLiteDatabase db = GlucosaDaoImpl.getInstance(this.getContext()).getReadableDatabase();

		// Define a projection that specifies which columns from the database
		// you will actually use after this query.
		String[] projection = { DiabecoContract.RegistroGlucosa._ID,
				DiabecoContract.RegistroGlucosa.COLUMNA_ALIAS,
				DiabecoContract.RegistroGlucosa.COLUMNA_FECHA,
				DiabecoContract.RegistroGlucosa.COLUMNA_CANTIDAD,
				DiabecoContract.RegistroGlucosa.COLUMNA_UM_GLUCOSA,
				DiabecoContract.RegistroGlucosa.COLUMNA_NIVEL_RIESGO,
				DiabecoContract.RegistroGlucosa.COLUMNA_ICON_RESOURCE_ID,
				DiabecoContract.RegistroGlucosa.COLUMNA_MOMENTO,
				DiabecoContract.RegistroGlucosa.COLUMNA_CUANDO,
				DiabecoContract.RegistroGlucosa.COLUMNA_MUJER,
				DiabecoContract.RegistroGlucosa.COLUMNA_OBSERVACIONES,
				DiabecoContract.RegistroGlucosa.COLUMNA_NOTA };

		Cursor cursor;
		String sortOrder = DiabecoContract.RegistroGlucosa.COLUMNA_FECHA + " DESC";
		
		String selectionObs = "";
		String selectionArgsObs = "";
		
		if (observaciones != 0) {
			int valorObs = Long.valueOf(observaciones).intValue();
			selectionObs = DiabecoContract.RegistroGlucosa.COLUMNA_OBSERVACIONES + " LIKE %?%";
			switch (valorObs){
			case 1:
				selectionArgsObs = Glucosa.ENFERMEDAD;
				break;
			case 2:
				selectionArgsObs = Glucosa.STRESS;
				break;
			case 3:
				selectionArgsObs = Glucosa.VACACIONES;
				break;
			case 4:
				selectionArgsObs = Glucosa.SIN_OBSERVACIONES;
				break;
				}
		}			
		
		
		if (rango == 3){
			String selection = DiabecoContract.RegistroGlucosa.COLUMNA_FECHA + " >= ? AND " + DiabecoContract.RegistroGlucosa.COLUMNA_FECHA + " <= ? ";
			if (observaciones!=0){
				selection += " AND " + DiabecoContract.RegistroGlucosa.COLUMNA_OBSERVACIONES + " LIKE ?";
				String[] selectionArgs = {String.valueOf(fromDate.getTimeInMillis()), String.valueOf(toDate.getTimeInMillis()), "%"+selectionArgsObs+"%"};

				// How you want the results sorted in the resulting Cursor
				cursor = db.query(DiabecoContract.RegistroGlucosa.TABLE_NAME, // The table to query
						projection, // The columns to return
						selection, // The columns for the WHERE clause
						selectionArgs, // The values for the WHERE clause
						null, // don't group the rows
						null, // don't filter by row groups
						sortOrder // The sort order
						);
			}
			else{
				String[] selectionArgs = {String.valueOf(fromDate.getTimeInMillis()), String.valueOf(toDate.getTimeInMillis())};
				

				// How you want the results sorted in the resulting Cursor
				cursor = db.query(DiabecoContract.RegistroGlucosa.TABLE_NAME, // The table to query
						projection, // The columns to return
						selection, // The columns for the WHERE clause
						selectionArgs, // The values for the WHERE clause
						null, // don't group the rows
						null, // don't filter by row groups
						sortOrder // The sort order
						);
			}
			
			
			
			
		
		}
		else {
			if (observaciones!=0){
					String selection = DiabecoContract.RegistroGlucosa.COLUMNA_FECHA + " >= ? AND " + DiabecoContract.RegistroGlucosa.COLUMNA_FECHA + " <= ? ";
		//String[] selectionArgs = {String.valueOf(fromDate.getTimeInMillis()), String.valueOf(toDate.getTimeInMillis())};
		String[] selectionArgs = {String.valueOf(fromDate.getTimeInMillis()), String.valueOf(toDate.getTimeInMillis()), 
				String.valueOf(umbralBajo), String.valueOf(umbralAlto), "%"+selectionArgsObs+"%"};
	
		String selection2 = "";
		int valor = Long.valueOf(rango).intValue();
		switch (valor) {
		case 0: selection2 = " AND " + DiabecoContract.RegistroGlucosa.COLUMNA_CANTIDAD + " >= ? AND " + 
							 DiabecoContract.RegistroGlucosa.COLUMNA_CANTIDAD + " <= ? ";
				selection2 += " AND " + DiabecoContract.RegistroGlucosa.COLUMNA_OBSERVACIONES + " LIKE ?";
				selection+=selection2; 
		
				break;
			
		case 1: selection2 = " AND " + DiabecoContract.RegistroGlucosa.COLUMNA_CANTIDAD + " <= ? AND " + 
							 DiabecoContract.RegistroGlucosa.COLUMNA_CANTIDAD + " <= ?";
				selection2 += " AND " + DiabecoContract.RegistroGlucosa.COLUMNA_OBSERVACIONES + " LIKE ?";
				selection+=selection2;
				break;
		case 2: selection2 = " AND " + DiabecoContract.RegistroGlucosa.COLUMNA_CANTIDAD + " >= ? AND " + 
				 			 DiabecoContract.RegistroGlucosa.COLUMNA_CANTIDAD + " >= ?";
				selection2 += " AND " + DiabecoContract.RegistroGlucosa.COLUMNA_OBSERVACIONES + " LIKE ?";
				selection+=selection2;
				break;
		}
		
		
		cursor = db.query(DiabecoContract.RegistroGlucosa.TABLE_NAME, // The table to query
				projection, // The columns to return
				selection, // The columns for the WHERE clause
				selectionArgs, // The values for the WHERE clause
				null, // don't group the rows
				null, // don't filter by row groups
				sortOrder // The sort order
				);
		}else {
							String selection = DiabecoContract.RegistroGlucosa.COLUMNA_FECHA + " >= ? AND " + DiabecoContract.RegistroGlucosa.COLUMNA_FECHA + " <= ? ";
				//String[] selectionArgs = {String.valueOf(fromDate.getTimeInMillis()), String.valueOf(toDate.getTimeInMillis())};
				String[] selectionArgs = {String.valueOf(fromDate.getTimeInMillis()), String.valueOf(toDate.getTimeInMillis()), 
						String.valueOf(umbralBajo), String.valueOf(umbralAlto)};
				
				String selection2 = "";
				int valor = Long.valueOf(rango).intValue();
				switch (valor) {
				case 0: selection2 = " AND " + DiabecoContract.RegistroGlucosa.COLUMNA_CANTIDAD + " >= ? AND " + 
									 DiabecoContract.RegistroGlucosa.COLUMNA_CANTIDAD + " <= ?";
						selection+=selection2;
				
						break;
					
				case 1: selection2 = " AND " + DiabecoContract.RegistroGlucosa.COLUMNA_CANTIDAD + " <= ? AND " + 
									 DiabecoContract.RegistroGlucosa.COLUMNA_CANTIDAD + " <= ?";
						selection+=selection2;
						break;
				case 2: selection2 = " AND " + DiabecoContract.RegistroGlucosa.COLUMNA_CANTIDAD + " >= ? AND " + 
						 			 DiabecoContract.RegistroGlucosa.COLUMNA_CANTIDAD + " >= ?";
						selection+=selection2;
						break;
				}
				
				
				cursor = db.query(DiabecoContract.RegistroGlucosa.TABLE_NAME, // The table to query
						projection, // The columns to return
						selection, // The columns for the WHERE clause
						selectionArgs, // The values for the WHERE clause
						null, // don't group the rows
						null, // don't filter by row groups
						sortOrder // The sort order
						);
							
						}
						
		}

		while (cursor.moveToNext()) {
			Glucosa glucosa = this.retrieveGlycemiaMeasureFromCursor(cursor);
			result.add(glucosa);
		}

		return result;
	}

	public void save(Glucosa glucosa) {

		// Gets the data repository in write mode
		SQLiteDatabase db = GlucosaDaoImpl.getInstance(this.getContext()).getWritableDatabase();

		// Create a new map of values, where column names are the keys
		ContentValues values = new ContentValues();
		values.put(DiabecoContract.RegistroGlucosa.COLUMNA_ALIAS, glucosa.getAlias());
		values.put(DiabecoContract.RegistroGlucosa.COLUMNA_FECHA, glucosa.getFecha());
		values.put(DiabecoContract.RegistroGlucosa.COLUMNA_CANTIDAD, glucosa.getCantidad());
		values.put(DiabecoContract.RegistroGlucosa.COLUMNA_UM_GLUCOSA, glucosa.getUmGlucosa());
		values.put(DiabecoContract.RegistroGlucosa.COLUMNA_NIVEL_RIESGO, glucosa.getNivelRiego());
		values.put(DiabecoContract.RegistroGlucosa.COLUMNA_ICON_RESOURCE_ID, glucosa.getIconResourceId());
		values.put(DiabecoContract.RegistroGlucosa.COLUMNA_MOMENTO, glucosa.getMomento());
		values.put(DiabecoContract.RegistroGlucosa.COLUMNA_CUANDO, glucosa.getCuando());
		values.put(DiabecoContract.RegistroGlucosa.COLUMNA_MUJER, glucosa.getMujer());
		values.put(DiabecoContract.RegistroGlucosa.COLUMNA_OBSERVACIONES, glucosa.getObservaciones());
		values.put(DiabecoContract.RegistroGlucosa.COLUMNA_NOTA, glucosa.getNotas());
		
	
		long rowId;
		if (glucosa.getId() != null) {
			rowId = db.update(DiabecoContract.RegistroGlucosa.TABLE_NAME, values,
					DiabecoContract.RegistroGlucosa._ID + " = ?", new String[] { glucosa.getId().toString() });
		} else {
			// Insert the new row, returning the primary key value of the new row
			rowId = db.insert(DiabecoContract.RegistroGlucosa.TABLE_NAME, null, values);
		}
		
		System.out.println("Registros de glucosa grabados en la base de datos: " + rowId);
		db.close();
	}

	
	@Override
	public void deleteById(Long id) {

		// Gets the data repository in write mode
		SQLiteDatabase db = GlucosaDaoImpl.getInstance(this.getContext()).getWritableDatabase();

		String removeId = id.toString();

		int rowsDeleted = db.delete(DiabecoContract.RegistroGlucosa.TABLE_NAME, DiabecoContract.RegistroGlucosa._ID
				+ "=?", new String[] { removeId });

		if (rowsDeleted != 1) {
			throw new RuntimeException("No se pudo eliminar el registro con id " + id);
		}
		
		db.close();

	}

	@Override
	public void clear() {
		// TODO Auto-generated method stub

	}

	private Glucosa retrieveGlycemiaMeasureFromCursor(Cursor cursor) {
		Glucosa glucosa = new Glucosa();

		Long id = cursor.getLong(cursor.getColumnIndexOrThrow(DiabecoContract.RegistroGlucosa._ID));
		String alias = cursor.getString(cursor.getColumnIndexOrThrow(DiabecoContract.RegistroGlucosa.COLUMNA_ALIAS));
		Long fecha = cursor.getLong(cursor
				.getColumnIndexOrThrow(DiabecoContract.RegistroGlucosa.COLUMNA_FECHA));
		Float cantidad = cursor.getFloat(cursor
				.getColumnIndexOrThrow(DiabecoContract.RegistroGlucosa.COLUMNA_CANTIDAD));
		String umGlucosa = cursor.getString(cursor
				.getColumnIndexOrThrow(DiabecoContract.RegistroGlucosa.COLUMNA_UM_GLUCOSA));
		String nivelRiesgo = cursor.getString(cursor
				.getColumnIndexOrThrow(DiabecoContract.RegistroGlucosa.COLUMNA_NIVEL_RIESGO));
		Integer iconResourceId = cursor.getInt(cursor
				.getColumnIndexOrThrow(DiabecoContract.Medicamento.COLUMNA_ICON_RESOURCE_ID));
		String momento = cursor.getString(cursor
				.getColumnIndexOrThrow(DiabecoContract.RegistroGlucosa.COLUMNA_MOMENTO));
		String cuando = cursor.getString(cursor
				.getColumnIndexOrThrow(DiabecoContract.RegistroGlucosa.COLUMNA_CUANDO));
		String mujer = cursor.getString(cursor
				.getColumnIndexOrThrow(DiabecoContract.RegistroGlucosa.COLUMNA_MUJER));
		String observaciones = cursor.getString(cursor
				.getColumnIndexOrThrow(DiabecoContract.RegistroGlucosa.COLUMNA_OBSERVACIONES));
		String notas = cursor.getString(cursor
				.getColumnIndexOrThrow(DiabecoContract.RegistroGlucosa.COLUMNA_NOTA));
				
		
		glucosa.setId(id);
		glucosa.setAlias(alias);
		glucosa.setFecha(fecha);
		glucosa.setCantidad(cantidad);
		glucosa.setUmGlucosa(umGlucosa);
		glucosa.setNivelRiego(nivelRiesgo);
		glucosa.setIconResourceId(iconResourceId);
		glucosa.setCuando(cuando);
		glucosa.setMomento(momento);
		glucosa.setMujer(mujer);
		glucosa.setObservaciones(observaciones);
		glucosa.setNotas(notas);
		
		System.out.println("Glucemia Leida: " + glucosa);

		return glucosa;
	}

}
